#region Using Statements
using System;
using System.Collections.Generic;//using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion



namespace Pauliver
{
    [Serializable]
    class SpriteSheet
    {
        public Texture2D _SpriteSheet;
        public Rectangle _BoxSize;
        Rectangle _CurrentSquare;
        String _Name;
        int _BoxesWide;
        int _BoxesTall;
        int _CurrentIndex;
        int _MaxIndex;
        int _frames_per_sprite; //number of seconds to show each sprite
        int _counter;
        
        protected bool IndexChanged;

        public SpriteSheet(Texture2D p_spritesheet, Rectangle p_BoxSize, String p_Name,int fps)
        {
            _frames_per_sprite = fps;
            _counter = 0;
            _SpriteSheet = p_spritesheet;
            _BoxSize = p_BoxSize;
            _Name = p_Name;
            _MaxIndex = 0;
            _BoxesWide = p_spritesheet.Width / p_BoxSize.Width;
            _BoxesTall = p_spritesheet.Height / p_BoxSize.Height;
            _MaxIndex = _BoxesWide * _BoxesTall;
            _CurrentIndex = 0;
        }

        public void Reset()
        {
            _CurrentIndex = 0;
            _counter = 0;
        }

        public bool AtLastFrame()
        {
            return (_CurrentIndex == _MaxIndex -1);
        }

        public void Update(GameTime p_time)
        {
            int x = (_CurrentIndex / _BoxesTall) * _BoxSize.Width;
            int y = (_CurrentIndex % _BoxesTall) * _BoxSize.Height;
            _CurrentSquare = new Rectangle(x, y, _BoxSize.Width, _BoxSize.Height);
            if (_counter++ == _frames_per_sprite)
            {
                _counter = 0; 
                IndexChanged = true;
                if (++_CurrentIndex >= _MaxIndex)
                {
                    _CurrentIndex = 0;
                }
            }
        }

        public bool FrameChanged
        {
            get
            {
                return IndexChanged;
            }
        }

        public void Draw(SpriteBatch p_SpriteBatch, GameTime p_GameTime, Rectangle p_Screen, Color DrawColor, float Scale, float DrawLayer, Vector2 Position, float Rotation)
        {
            Rectangle target = new Rectangle((int)Position.X - p_Screen.X, (int)Position.Y - p_Screen.Y, _BoxSize.Width, _BoxSize.Height);
            p_SpriteBatch.Draw(_SpriteSheet, target, _CurrentSquare, DrawColor, Rotation, new Vector2((int)_BoxSize.Width / 2, (int)_BoxSize.Height / 2), SpriteEffects.None, DrawLayer);
        }
    }



    [Serializable]
    class Drawable_Sprite_Animated : DrawableComponent
    {
        System.Collections.Hashtable _SpriteSheetList;
        String _CurrentSprite;
        bool _CurrentlyPlaying;
        String _NextSprite;

        public string CurrentlyPlaying
        {
            get
            {
                return _CurrentSprite;
            }
        }

        public Drawable_Sprite_Animated()
        {
            _CurrentlyPlaying = false;
            base._Type = ComponentType.Drawable_Sprite_Animated;
            _SpriteSheetList = new System.Collections.Hashtable();
        }

        public override void Update(GameTime p_time)
        {
            if (_CurrentlyPlaying)
            {
                SpriteSheet ss = (_SpriteSheetList[_CurrentSprite] as SpriteSheet);
                bool LastFrame = ss.AtLastFrame();
                ss.Update(p_time);
                if (LastFrame && _NextSprite != null)
                {
                    SetCurrentAnimation(_NextSprite);
                }
            }
        }

        public void SetupAnimation(Texture2D p_SpriteSheet, Rectangle p_BoxSize, String p_Name, int fps)
        {
            origin = new Vector2(p_BoxSize.Width / 2.0f, p_BoxSize.Height / 2.0f);
            SpriteSheet ss = new SpriteSheet(p_SpriteSheet, p_BoxSize, p_Name, fps);
            _SpriteSheetList[p_Name] = ss;
        }

        public void SetCurrentAnimation(String p_AnimationName, String p_NextAnimationName)
        {
            SetCurrentAnimation(p_AnimationName);
            _NextSprite = p_NextAnimationName;
        }


        public void SetCurrentAnimation(String p_AnimationName)
        {
            _CurrentlyPlaying = true;
            (_SpriteSheetList[p_AnimationName] as SpriteSheet).Reset();
            _CurrentSprite = p_AnimationName;
            _NextSprite = null;
        }

        float Scale = 1.0f;
        float DrawLayer = 0.90f;
        float Rotation = 0.0f;
        public override void Draw(SpriteBatch p_SpriteBatch, GameTime p_GameTime, Rectangle p_Screen)
        {            
            Rotation = (base.Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation;
            
            dl = (base.Parent[ComponentType.DrawLayer] as DrawLayer);
            if (dl!= null)
            {
                DrawLayer = dl.Layer;
            }

            DrawColor = Color.White;
            gt = (Parent[ComponentType.Game_Team] as Game_Team);
            if (gt != null)
            {
                DrawColor = gt.TeamColor();
            }

            position = (base.Parent[ComponentType.Game_Position] as Game_Position).Position;

            (_SpriteSheetList[_CurrentSprite] as SpriteSheet).Draw(p_SpriteBatch, p_GameTime, p_Screen, DrawColor, Scale, DrawLayer, position, Rotation);
        }

        public void StopAnimation()
        {
            _CurrentlyPlaying = false;
        }
    }
}